type HttpArgs = { [key: string]: any }


/**
 * @description http 管理器
 * @author mirahs
 * @email 2892727493@qq.com
 */
export default class HttpMgr {
    public static get(url: string, args?: HttpArgs, retJson?: boolean) {
        return this.request(url, 'GET', args, retJson)
    }

    public static post(url: string, args?: HttpArgs, retJson?: boolean) {
        return this.request(url, 'POST', args, retJson)
    }

    public static put(url: string, args?: HttpArgs, retJson?: boolean) {
        return this.request(url, 'PUT', args, retJson)
    }

    public static patch(url: string, args?: HttpArgs, retJson?: boolean) {
        return this.request(url, 'PATCH', args, retJson)
    }

    public static delete(url: string, args?: HttpArgs, retJson?: boolean) {
        return this.request(url, 'DELETE', args, retJson)
    }


    private static request(url: string, method: string, args?: HttpArgs, retJson?: boolean) {
        return new Promise<any>((resolve, reject) => {
            const xhr = cc.loader.getXMLHttpRequest()

            xhr.timeout = 10000
            xhr.ontimeout = () => {
                reject({ code: -1, msg: '网络异常(timeout)' })
            }
            xhr.onerror = () => {
                reject({ code: -1, msg: '网络异常(error)' })
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState != 4) return

                const res = xhr.responseText
                if (!res || !retJson) {
                    resolve({ code: 0, data: res })
                    return
                }

                try {
                    resolve(JSON.parse(res))
                } catch (error) {
                    reject({ code: -1, msg: '网络异常(res error):' + error })
                }
            }

            const httpParams = this.args2HttpParams(args)

            if (method == 'GET') {
                url = httpParams == '' ? url : url + '?' + httpParams
                xhr.open(method, url, true)
                xhr.send()
            } else {
                xhr.open(method, url, true)
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                xhr.send(httpParams)
            }
        })
    }


    private static args2HttpParams(args: HttpArgs): string {
        if (!args) return ''

        let content = ''

        for (const key in args) {
            const val = args[key]

            if (Array.isArray(val)) {
                for (const x of val) {
                    content += key + '=' + x + '&'
                }
            } else {
                content += key + '=' + val + '&'
            }
        }

        return content.substring(0, content.length - 1)
    }
}
